/// gcc -o subscribe_redis parse.c -lhiredis

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <hiredis/hiredis.h>

// 回调函数，当有新消息到达订阅的频道时被调用
void message_handler(redisContext *c, void *privdata, const redisReply *reply) {
    if (reply->type == REDIS_REPLY_ARRAY && reply->elements == 3) {
	/// 0 message 1 key 2 content
        if (strcmp(reply->element[0]->str, "message") == 0) {
            printf("Received message on channel %s: %s len:%ld\n", reply->element[1]->str, reply->element[2]->str, reply->element[2]->len);
        }
    }
}

int main() {
    // 连接到Redis服务器
    redisContext *c = redisConnect("192.168.0.105", 6379); // 使用您的Redis服务器IP
    if (c == NULL || c->err) {
        if (c) {
            printf("Connection error: %s", c->errstr);
            redisFree(c);
        } else {
            printf("Connection error: can't allocate redis context");
        }
        return 1;
    }

    // 订阅频道
    redisReply *reply;
    reply = redisCommand(c, "SUBSCRIBE packet_queue"); // 订阅packet_queue频道
    if (reply == NULL) {
        printf("Subscription error: %s", c->errstr);
        redisFree(c);
        return 1;
    }
    freeReplyObject(reply);

    // 处理服务器响应
    int ret = 0;
    // 开始监听消息
    while (1) {
        ret = redisGetReply(c, (void **)&reply); // 读取服务器响应
        if(ret != REDIS_OK) {
            if(c->err == REDIS_ERR_IO) { // 如果是网络错误，则退出循环
                printf("Connection error: %s", c->errstr);
                break;
            } 
            else if(c->err == REDIS_ERR_EOF) { // 如果是连接断开，则退出循环
                printf("Connection closed by server.\n");
                break;
            }
            else { // 其他错误
                printf("Error: %s\n", c->errstr);
                break;
            }
        }
        if (reply && reply->type == REDIS_REPLY_ARRAY) {
            message_handler(c, NULL, reply);
        }
        freeReplyObject(reply);
    }

    // 断开连接
    redisFree(c);
    return 0;
}
